import React, { useState, useEffect, useCallback, useMemo } from 'react'
import {
  List,
  Card,
  Typography,
  Tag,
  Button,
  Dropdown,
  Checkbox,
  Tooltip,
  Space,
  Empty,
  Spin,
  message,
  Modal,
  Pagination,
  Row,
  Col,
} from 'antd'
import {
  PlayCircleOutlined,
  EditOutlined,
  CopyOutlined,
  DeleteOutlined,
  MoreOutlined,
  FileTextOutlined,
  CalendarOutlined,
  UserOutlined,
  TagOutlined,
  EyeOutlined,
  DragOutlined,
} from '@ant-design/icons'
import { DndProvider, useDrag, useDrop } from 'react-dnd'
import { HTML5Backend } from 'react-dnd-html5-backend'
import { Script } from '@/types/script'
import { getScripts, deleteScript, copyScript, moveScript } from '@/services/scriptAPI'
import { formatDistanceToNow } from 'date-fns'
import { zhCN } from 'date-fns/locale'

const { Text, Paragraph } = Typography
const { confirm } = Modal

interface ScriptListProps {
  folderId?: string | null
  searchKeyword?: string
  selectedTags?: string[]
  sortBy?: 'name' | 'created_at' | 'updated_at' | 'last_executed_at'
  sortOrder?: 'asc' | 'desc'
  onScriptSelect?: (script: Script) => void
  onScriptExecute?: (script: Script) => void
  onSelectionChange?: (scriptIds: string[]) => void
  selectedScriptId?: string
  allowDrag?: boolean
  allowBulkSelect?: boolean
  pageSize?: number
}

interface DragItem {
  type: string
  id: string
  index: number
}

const ITEM_TYPE = 'SCRIPT_ITEM'

// 可拖拽的脚本项组件
const DraggableScriptItem: React.FC<{
  script: Script
  index: number
  isSelected: boolean
  isActive: boolean
  allowDrag: boolean
  allowBulkSelect: boolean
  onSelect: (script: Script) => void
  onExecute: (script: Script) => void
  onEdit: (script: Script) => void
  onCopy: (script: Script) => void
  onDelete: (script: Script) => void
  onPreview: (script: Script) => void
  onCheckChange: (scriptId: string, checked: boolean) => void
  onMove: (dragIndex: number, hoverIndex: number) => void
}> = ({
  script,
  index,
  isSelected,
  isActive,
  allowDrag,
  allowBulkSelect,
  onSelect,
  onExecute,
  onEdit,
  onCopy,
  onDelete,
  onPreview,
  onCheckChange,
  onMove,
}) => {
  const [{ isDragging }, drag, dragPreview] = useDrag({
    type: ITEM_TYPE,
    item: { type: ITEM_TYPE, id: script.id, index },
    collect: (monitor) => ({
      isDragging: monitor.isDragging(),
    }),
    canDrag: allowDrag,
  })

  const [, drop] = useDrop({
    accept: ITEM_TYPE,
    hover: (item: DragItem) => {
      if (!allowDrag) return
      
      const dragIndex = item.index
      const hoverIndex = index

      if (dragIndex === hoverIndex) return

      onMove(dragIndex, hoverIndex)
      item.index = hoverIndex
    },
  })

  // 操作菜单
  const actionMenuItems = [
    {
      key: 'preview',
      icon: <EyeOutlined />,
      label: '预览',
      onClick: () => onPreview(script),
    },
    {
      key: 'edit',
      icon: <EditOutlined />,
      label: '编辑',
      onClick: () => onEdit(script),
    },
    {
      key: 'copy',
      icon: <CopyOutlined />,
      label: '复制',
      onClick: () => onCopy(script),
    },
    {
      type: 'divider' as const,
    },
    {
      key: 'delete',
      icon: <DeleteOutlined />,
      label: '删除',
      danger: true,
      onClick: () => onDelete(script),
    },
  ]

  const cardRef = useCallback((node: HTMLDivElement) => {
    if (allowDrag) {
      drag(drop(node))
    }
  }, [drag, drop, allowDrag])

  return (
    <div ref={dragPreview} style={{ opacity: isDragging ? 0.5 : 1 }}>
      <Card
        ref={cardRef}
        size="small"
        hoverable
        className={`script-item ${isActive ? 'active' : ''} ${isSelected ? 'selected' : ''}`}
        style={{
          marginBottom: 8,
          cursor: allowDrag ? 'move' : 'pointer',
          border: isActive ? '2px solid #1890ff' : undefined,
          backgroundColor: isSelected ? '#f6ffed' : undefined,
        }}
        onClick={() => onSelect(script)}
        bodyStyle={{ padding: '12px 16px' }}
        actions={[
          <Button
            key="execute"
            type="text"
            icon={<PlayCircleOutlined />}
            size="small"
            onClick={(e) => {
              e.stopPropagation()
              onExecute(script)
            }}
          >
            执行
          </Button>,
          <Dropdown
            key="more"
            menu={{ items: actionMenuItems }}
            trigger={['click']}
            placement="bottomRight"
          >
            <Button
              type="text"
              icon={<MoreOutlined />}
              size="small"
              onClick={(e) => e.stopPropagation()}
            />
          </Dropdown>,
        ]}
      >
        <Row gutter={[8, 4]} align="middle">
          {/* 批量选择复选框 */}
          {allowBulkSelect && (
            <Col flex="none">
              <Checkbox
                checked={isSelected}
                onChange={(e) => {
                  e.stopPropagation()
                  onCheckChange(script.id, e.target.checked)
                }}
                onClick={(e) => e.stopPropagation()}
              />
            </Col>
          )}

          {/* 拖拽手柄 */}
          {allowDrag && (
            <Col flex="none">
              <DragOutlined style={{ color: '#999', cursor: 'grab' }} />
            </Col>
          )}

          {/* 脚本图标 */}
          <Col flex="none">
            <FileTextOutlined style={{ fontSize: 16, color: '#1890ff' }} />
          </Col>

          {/* 脚本信息 */}
          <Col flex="auto">
            <div>
              <Text strong style={{ fontSize: 14 }}>
                {script.name}
              </Text>
              {script.description && (
                <Paragraph
                  ellipsis={{ rows: 1, tooltip: script.description }}
                  style={{ margin: '4px 0 0 0', color: '#666', fontSize: 12 }}
                >
                  {script.description}
                </Paragraph>
              )}
            </div>

            {/* 标签 */}
            {script.tags && script.tags.length > 0 && (
              <div style={{ marginTop: 8 }}>
                {script.tags.slice(0, 3).map((tag) => (
                  <Tag key={tag} size="small" color="blue">
                    {tag}
                  </Tag>
                ))}
                {script.tags.length > 3 && (
                  <Tag size="small" color="default">
                    +{script.tags.length - 3}
                  </Tag>
                )}
              </div>
            )}

            {/* 元数据 */}
            <div style={{ marginTop: 8, fontSize: 12, color: '#999' }}>
              <Space size={16}>
                <Tooltip title="创建者">
                  <Space size={4}>
                    <UserOutlined />
                    <Text type="secondary">{script.created_by}</Text>
                  </Space>
                </Tooltip>
                <Tooltip title="更新时间">
                  <Space size={4}>
                    <CalendarOutlined />
                    <Text type="secondary">
                      {formatDistanceToNow(new Date(script.updated_at), {
                        addSuffix: true,
                        locale: zhCN,
                      })}
                    </Text>
                  </Space>
                </Tooltip>
                {script.version_count && (
                  <Tooltip title="版本数量">
                    <Text type="secondary">{script.version_count} 个版本</Text>
                  </Tooltip>
                )}
              </Space>
            </div>
          </Col>
        </Row>
      </Card>
    </div>
  )
}

const ScriptList: React.FC<ScriptListProps> = ({
  folderId,
  searchKeyword,
  selectedTags = [],
  sortBy = 'updated_at',
  sortOrder = 'desc',
  onScriptSelect,
  onScriptExecute,
  onSelectionChange,
  selectedScriptId,
  allowDrag = true,
  allowBulkSelect = true,
  pageSize = 20,
}) => {
  const [scripts, setScripts] = useState<Script[]>([])
  const [loading, setLoading] = useState(false)
  const [total, setTotal] = useState(0)
  const [currentPage, setCurrent] = useState(1)
  const [selectedScripts, setSelectedScripts] = useState<string[]>([])
  const [previewScript, setPreviewScript] = useState<Script | null>(null)

  // 加载脚本列表
  const loadScripts = useCallback(async () => {
    setLoading(true)
    try {
      const response = await getScripts({
        keyword: searchKeyword,
        tags: selectedTags.length > 0 ? selectedTags : undefined,
        folder_id: folderId || undefined,
        limit: pageSize,
        offset: (currentPage - 1) * pageSize,
      })

      if (response.success) {
        let scriptList = response.data.scripts || []
        
        // 客户端排序
        scriptList.sort((a, b) => {
          let aValue: any = a[sortBy]
          let bValue: any = b[sortBy]
          
          if (sortBy.includes('_at')) {
            aValue = new Date(aValue).getTime()
            bValue = new Date(bValue).getTime()
          }
          
          if (sortOrder === 'asc') {
            return aValue > bValue ? 1 : -1
          } else {
            return aValue < bValue ? 1 : -1
          }
        })
        
        setScripts(scriptList)
        setTotal(response.data.total || 0)
      }
    } catch (error) {
      console.error('加载脚本列表失败:', error)
      message.error('加载脚本列表失败')
    } finally {
      setLoading(false)
    }
  }, [folderId, searchKeyword, selectedTags, sortBy, sortOrder, currentPage, pageSize])

  // 处理脚本选择
  const handleScriptSelect = (script: Script) => {
    onScriptSelect?.(script)
  }

  // 处理脚本执行
  const handleScriptExecute = (script: Script) => {
    onScriptExecute?.(script)
  }

  // 处理脚本编辑
  const handleScriptEdit = (script: Script) => {
    onScriptSelect?.(script)
  }

  // 处理脚本复制
  const handleScriptCopy = async (script: Script) => {
    try {
      const response = await copyScript(script.id, {
        name: `${script.name} - 副本`,
        folder_id: folderId || undefined,
      })
      
      if (response.success) {
        message.success('脚本复制成功')
        loadScripts()
      }
    } catch (error) {
      console.error('复制脚本失败:', error)
      message.error('复制脚本失败')
    }
  }

  // 处理脚本删除
  const handleScriptDelete = (script: Script) => {
    confirm({
      title: '确认删除',
      content: `确定要删除脚本 "${script.name}" 吗？此操作不可撤销。`,
      okText: '删除',
      okType: 'danger',
      cancelText: '取消',
      onOk: async () => {
        try {
          const response = await deleteScript(script.id)
          if (response.success) {
            message.success('脚本删除成功')
            loadScripts()
          }
        } catch (error) {
          console.error('删除脚本失败:', error)
          message.error('删除脚本失败')
        }
      },
    })
  }

  // 处理脚本预览
  const handleScriptPreview = (script: Script) => {
    setPreviewScript(script)
  }

  // 处理批量选择
  const handleCheckChange = (scriptId: string, checked: boolean) => {
    setSelectedScripts(prev => {
      const newSelection = checked 
        ? [...prev, scriptId]
        : prev.filter(id => id !== scriptId)
      
      onSelectionChange?.(newSelection)
      return newSelection
    })
  }

  // 处理全选
  const handleSelectAll = (checked: boolean) => {
    const newSelection = checked ? scripts.map(script => script.id) : []
    setSelectedScripts(newSelection)
    onSelectionChange?.(newSelection)
  }

  // 处理拖拽排序
  const handleMove = useCallback((dragIndex: number, hoverIndex: number) => {
    setScripts(prev => {
      const newScripts = [...prev]
      const draggedScript = newScripts[dragIndex]
      newScripts.splice(dragIndex, 1)
      newScripts.splice(hoverIndex, 0, draggedScript)
      return newScripts
    })
  }, [])

  // 处理分页变化
  const handlePageChange = (page: number, size?: number) => {
    setCurrent(page)
    if (size && size !== pageSize) {
      // 如果页面大小改变，重新加载
      loadScripts()
    }
  }

  // 计算选中状态
  const isAllSelected = scripts.length > 0 && selectedScripts.length === scripts.length
  const isIndeterminate = selectedScripts.length > 0 && selectedScripts.length < scripts.length

  // 初始化和依赖更新时加载数据
  useEffect(() => {
    setCurrent(1) // 重置到第一页
    loadScripts()
  }, [folderId, searchKeyword, selectedTags, sortBy, sortOrder])

  useEffect(() => {
    loadScripts()
  }, [currentPage])

  // 清除选中状态
  useEffect(() => {
    setSelectedScripts([])
  }, [folderId, searchKeyword, selectedTags])

  if (loading && scripts.length === 0) {
    return (
      <div style={{ 
        display: 'flex', 
        justifyContent: 'center', 
        alignItems: 'center', 
        height: 200 
      }}>
        <Spin size="large" />
      </div>
    )
  }

  if (!loading && scripts.length === 0) {
    return (
      <Empty
        image={Empty.PRESENTED_IMAGE_SIMPLE}
        description={
          searchKeyword || selectedTags.length > 0
            ? '没有找到匹配的脚本'
            : '暂无脚本，点击上方按钮创建第一个脚本'
        }
        style={{ padding: '40px 20px' }}
      />
    )
  }

  return (
    <DndProvider backend={HTML5Backend}>
      <div style={{ height: '100%', display: 'flex', flexDirection: 'column' }}>
        {/* 批量操作工具栏 */}
        {allowBulkSelect && selectedScripts.length > 0 && (
          <div style={{ 
            padding: '8px 16px', 
            backgroundColor: '#f0f9ff', 
            borderBottom: '1px solid #e6f7ff',
            display: 'flex',
            alignItems: 'center',
            justifyContent: 'space-between',
          }}>
            <Space>
              <Checkbox
                indeterminate={isIndeterminate}
                checked={isAllSelected}
                onChange={(e) => handleSelectAll(e.target.checked)}
              >
                已选择 {selectedScripts.length} 项
              </Checkbox>
            </Space>
            <Space>
              <Button size="small" onClick={() => setSelectedScripts([])}>
                取消选择
              </Button>
              <Button size="small" type="primary" ghost>
                批量操作
              </Button>
            </Space>
          </div>
        )}

        {/* 脚本列表 */}
        <div style={{ 
          flex: 1, 
          overflow: 'auto', 
          padding: '16px',
        }}>
          <Spin spinning={loading}>
            {scripts.map((script, index) => (
              <DraggableScriptItem
                key={script.id}
                script={script}
                index={index}
                isSelected={selectedScripts.includes(script.id)}
                isActive={script.id === selectedScriptId}
                allowDrag={allowDrag}
                allowBulkSelect={allowBulkSelect}
                onSelect={handleScriptSelect}
                onExecute={handleScriptExecute}
                onEdit={handleScriptEdit}
                onCopy={handleScriptCopy}
                onDelete={handleScriptDelete}
                onPreview={handleScriptPreview}
                onCheckChange={handleCheckChange}
                onMove={handleMove}
              />
            ))}
          </Spin>
        </div>

        {/* 分页 */}
        {total > pageSize && (
          <div style={{ 
            padding: '16px', 
            borderTop: '1px solid #f0f0f0',
            display: 'flex',
            justifyContent: 'center',
          }}>
            <Pagination
              current={currentPage}
              total={total}
              pageSize={pageSize}
              showSizeChanger
              showQuickJumper
              showTotal={(total, range) => 
                `第 ${range[0]}-${range[1]} 项，共 ${total} 项`
              }
              onChange={handlePageChange}
            />
          </div>
        )}

        {/* 脚本预览模态框 */}
        <Modal
          title={`预览: ${previewScript?.name}`}
          open={!!previewScript}
          onCancel={() => setPreviewScript(null)}
          footer={[
            <Button key="close" onClick={() => setPreviewScript(null)}>
              关闭
            </Button>,
            <Button 
              key="edit" 
              type="primary" 
              onClick={() => {
                if (previewScript) {
                  handleScriptEdit(previewScript)
                  setPreviewScript(null)
                }
              }}
            >
              编辑
            </Button>,
          ]}
          width={800}
        >
          {previewScript && (
            <div>
              {previewScript.description && (
                <div style={{ marginBottom: 16 }}>
                  <Text type="secondary">{previewScript.description}</Text>
                </div>
              )}
              <pre style={{ 
                backgroundColor: '#f5f5f5', 
                padding: 16, 
                borderRadius: 4,
                maxHeight: 400,
                overflow: 'auto',
                fontSize: 12,
                lineHeight: 1.5,
              }}>
                {previewScript.content || '// 暂无内容'}
              </pre>
            </div>
          )}
        </Modal>
      </div>
    </DndProvider>
  )
}

export default ScriptList